﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using NLog;

namespace ScrappyDB.Utilities
{
    public class Compare
    {
        private static readonly Logger log = LogManager.GetCurrentClassLogger();

        public static bool CompareEntities<T>(T expected, T actual)
        {
            foreach (PropertyInfo prop in expected.GetType().GetProperties())
            {
                if(prop.PropertyType.FullName.StartsWith("PacketPower"))
                {
                    //ignore these for now
                    continue;
                }

                Type t = prop.PropertyType;
                if (t.IsGenericType)
                {
                    if (t.Name == "List`1")
                    {
                        //TODO:
                        //for now we'll just ignore it and call it a match                       
                    }
                    else
                    {
                        //this is probably a ScrappyDbCollection?

                        //TODO:
                        //for now we'll just ignore it and call it a match
                    }
                }
                else
                {
                    if (prop.PropertyType.BaseType != null && prop.PropertyType.BaseType.FullName == "System.Array")
                    {
                        //TODO:
                        //for now we'll just ignore it and call it a match
                    }
                    else
                    {
                        if (prop.PropertyType == typeof(DateTime) && (DateTime)prop.GetValue(expected, null) == DateTime.MaxValue)
                        {
                            //an expected value of DateTime.MaxValue is a flag to ignore the comparison 
                            //(intended to get around auto create/update datetime values)
                            continue;
                        }

                        if (prop.GetValue(expected, null) != null || prop.GetValue(actual, null) != null)
                        {
                            if (prop.GetValue(actual, null) == null)
                            {
                                var error = string.Format("Property: {0} - expected value '{1}' did not match 'null'", prop.Name, prop.GetValue(expected, null));
                                log.Warn(error);
                                return false;
                            }

                            if (prop.GetValue(expected, null) == null)
                            {
                                var error = string.Format("Property: {0} - expected value 'null' did not match '{1}'", prop.Name, prop.GetValue(actual, null));
                                log.Warn(error);
                                return false;
                            }


                            if (prop.GetValue(expected, null).ToString() != prop.GetValue(actual, null).ToString())
                            {
                                var error = string.Format("Property: {0} - expected value '{1}' did not match '{2}'",
                                                          prop.Name,
                                                          prop.GetValue(expected, null), prop.GetValue(actual, null));
                                log.Warn(error);
                                return false;
                            }
                        }
                    }
                }
            }
            return true;
        }
    }
}
